<template>
  <Node :nodeComps="widgetComps" :nodeProps="{name:'root'}">
    <Sprite :spriteFrame="bkframe" :nodeProps="{name:'bkimg',scale:2}"/>
    <Node :nodeProps="{name:'di_layer'}">
      <Block v-for="(vs,i) in allvertexs.resvs" :key="i" :fillColor="rescolor" :vertexs="vs" :nodeProps="{name:'block_'+i}" />
    </Node >
    <Node :nodeProps="{name:'hint_layer',active:false}">
      <!-- <Block :fillColor="fillColor" :vertexs="vertexs" :nodeProps="{x:-80,y:-180}"/> -->
    </Node >
    <Node :nodeProps="{name:'opt_layer',active:true}">
      <Block v-for="(vs,i) in infos" :ref="`blk_${i}`" :key="i" :fillColor="blkcolors[i]" :vertexs="allvertexs.items[i]" :nodeProps="blockProps(i,vs)" />
    </Node >
    <Node ref="top" :nodeComps="widgetComps" :nodeProps="touchProps" />
    <Node :nodeProps="{name:'circlenode'}">
        <Node v-if="crlpt" :nodeProps="{name:'circle',x:crlpt.x,y:crlpt.y}">
            <Sprite ref="circle" :spriteFrame="rotframe" :nodeProps="{name:'circle',scale:crlpt.s,angle:crlpt.r}" />
            <Sprite :spriteFrame="rsvframe" :nodeComps="rsvComps" :nodeProps="{name:'btn',y:crlpt.h,onClick:handleClickRevers}" />
        </Node>
    </Node>
  </Node >
</template>

<script>
/* eslint-disable */

import throttle from 'lodash/throttle';
import fill from 'lodash/fill';
import {Node,Sprite} from "../cocos";
import Block from "./Block";

import {
    cals_node_vertexs,
    cals_xyrf_vertexs,
    vertexs_attach_polygon,
    vertexs_attach_line,
    vertexs_rotato_line,
    cc_p,cc_pAdd,cc_pSub,cc_pLengthSQ,cc_pDistance,cc_pDistanceSQ,cc_pAngleSigned,cc_rectContainsPoint,cc_pointInPolygon,cc_convertToNodeSpaceAR,
} from './qspolygonutil';

const ATTACH_MINDIS = 32;
const ATTACH_MINDIS_SQ = ATTACH_MINDIS * ATTACH_MINDIS;
const ATTACH_MINANG = 20;

const OPT_NAME_CIRCLE = 0;
const OPT_NAME_ORDER = 1;
const OPT_NAME_BLOCK = 2;
const OPT_NAME_POS = 3;
const OPT_NAME_ROT = 4;

export default {
  name: "Main",
  components: {
    Node,Block,Sprite,
  },
  props: {
    bkframe:null,
    rotframe:null,
    rsvframe:null,
    polyfile:null,

    cminRadius:{type: Number, default: 200},
    cmaxRadius:{type: Number, default: 300},
    circleRadius:{type: Number, default: 400},
    revbtnRadius:{type: Number, default: -340},

    blksz:{type: Number, default: 232},
    blkcap:{type: Number, default: 60},
    blkpt:{type:Object,default:()=>{return{ x: 0, y: -552 }}},
    respt:{type:Object,default:()=>{return{ x: -144, y: 198 }}},
    ressz:{type:Object,default:()=>{return{ width: 1580, height: 960 }}},

    rescolor:{type: String, default: '#888'},
    blkcolors:{type: Array, default:()=>{return ['#ea3410','#ffad0e','#ffec14','#93ff14','#52ffb8','#29deff','#1f5fe2','#9e3fff']}},
  },
  data() {
    let allvertexs = this.allvertexs;
    let infos = this.infos;
    if(!allvertexs){
      allvertexs = this.createAllVertexs();
      infos = this.createBlockInfo(allvertexs);
    }

    return {
      allvertexs,
      infos,

      crlpt:null,

      touchProps:{
        name:"touchlayer",
        onTouchStart:this.onTouchStart.bind(this),
        onTouchMove:this.onTouchMove.bind(this),
        onTouchEnd:this.onTouchEnd.bind(this),
        onTouchCancel:this.onTouchCancel.bind(this)
      },

      widgetComps:[
          {
              type: cc.Widget,
              props: {
                  isAlignTop: true,
                  isAlignLeft: true,
                  isAlignRight: true,
                  isAlignBottom: true,
                  alignMode:cc.Widget.AlignMode.ONCE,
              },
          }
      ],

      rsvComps:[
          {
              type: cc.Button,
              props: {
                  transition: cc.Button.Transition.SCALE,
                  zoomScale: 0.9,
              },
          }
      ],
    };
  },
  computed: {
    parentnode(){
      return this.$parent.ccnode;
    },
  },
  mounted() {
    // console.log("mounted polyfile",this.polyfile);
    this.throttlesend = throttle(this.sendUpdate.bind(this), 100, {
        leading: true,
        trailing: false,
    });
  },
  methods: {
    //////////////////////////////////
    onQuestionState(state){
        // console.log('onQuestionState', state);
        const {type,idx,value} = JSON.parse(state);
        switch(type){
            case OPT_NAME_ORDER:
                this.setStateBlockOrder(idx,false);
                break;
            case OPT_NAME_BLOCK:
                this.infos[idx] = value;
                this.updateState();
                break;
            case OPT_NAME_POS:
                {
                    let node = this.getBlockNode(idx);
                    node.x = value.x;
                    node.y = value.y;
                }
                break;
            case OPT_NAME_ROT:
                {
                    let node = this.getBlockNode(idx);
                    node.angle = value;
                }
                break;
            default:
                this.crlpt = value;
                break;
        }
    },
    //////////////////////////////////
    sendUpdate(type,idx,value){
        // sendState
        let state = {type,idx,value};
        // this.$parent.sendState(JSON.stringify(state));
    },
    //////////////////////////////////
    setStateCirclePos(crlpt){
        this.crlpt = crlpt;
        this.sendUpdate(OPT_NAME_CIRCLE,-1,crlpt);
    },
    setStateBlockOrder(index,touched){
        let infos = this.getInfos();
        let cinfo = infos[index];
        if(cinfo.z !== infos.length - 1){
          let z = cinfo.z;
          infos.forEach(info=>{
            if(info.z>z){
              info.z--;
            }
          });
          cinfo.z = infos.length - 1;
          this.updateState();

          if(touched){
              this.sendUpdate(OPT_NAME_ORDER,index,null);
          }
        }
    },
    setStateBlockInfo(idx,info){
        this.throttlesend.cancel();
        //{x:vs.x,y:vs.y,scaleX:vs.f ? -vs.s : vs.s,scaleY:vs.s,rotation:vs.r,zIndex:vs.z};
        this.infos[idx] = info;
        this.updateState();
        this.sendUpdate(OPT_NAME_BLOCK,idx,info);
    },
    setStateBlockRot(idx,rot){
        this.throttlesend(OPT_NAME_ROT,idx,rot);
    },
    setStateBlockPos(idx,pos){
        this.throttlesend(OPT_NAME_POS,idx,pos);
    },
    //////////////////////////////////
    // 相当于setQuestionState 在选中板块更改显示顺序，在操作结束，在移动到预备区时调用
    // 还有个影响显示的是crlpt，代表显示旋转翻转操作
    updateState(){
      let infos = this.getInfos().slice(0);
      this.infos = infos;
      // console.log("updateState",infos);
    },
    handleClickRevers(){
      // console.log("handleClickRevers");
      // if (this.props.questionState.showhint) {
      //     return;
      // }
      let orders = this.getOrders();
      let idx = orders[orders.length - 1];
      this.onPictureReserve(idx);
    },
    //////////////////////////////////
    onTouchStart(e) {
      // if (this.props.questionState.showhint) {
      //     return;
      // }
      // console.log("onTouchStart",this,e);

      e.stopPropagation();
      this.isTouching = true;
      this.isMoving = false;
      this.currTouchNode = null;
      this.curTouchInfo = null;
      this.handleTouchStart(e.touch);
    },
    onTouchMove(e) {
      // console.log("onTouchMove",e);
      e.stopPropagation();
      if (this.isTouching) {
        let delta = e.touch.getDelta();
        if (delta.x !== 0 || delta.y !== 0) {
            if (!this.isMoving) {
                if (this.currTouchNode) {
                    let idx = this.currTouchNode.block_idx;//parseInt(this.currTouchNode.name);
                    let infos = this.getInfos();
                    if (!infos[idx].i) {
                        this.currTouchNode.scaleX = 1;
                        this.currTouchNode.scaleY = 1;
                    }
                }
            }
            this.isMoving = true;
            this.handleTouchMove(delta, e.touch);
        }
      }
    },
    onTouchEnd(e) {
      // console.log("onTouchEnd",this,e);
      e.stopPropagation();
      if (this.isTouching) {
        this.isTouching = false;
        if (this.isMoving) {
            // this.dragging.cancel();
            this.handleTouchEnd(e.touch.getDelta(), e.touch);
        } else {
            this.handleClick(e.touch);
        }
      }
    },
    onTouchCancel(e) {
      // console.log("onTouchCancel",e);
      if (this.isTouching) {
          this.isTouching = false;
          if (this.isMoving) {
              // this.dragging.cancel();
              this.handleTouchEnd();
          }
      }
    },

    //////////////////////////////////
    getTopNode() {
      return this.$refs.top.ccnode;
    },
    getOrders(){
      let orders = fill(Array(this.infos.length), 0);
      this.infos.forEach((vs,i)=>{
        orders[vs.z] = i;
      });
      return orders;
    },
    getAllVers(){
      return this.allvertexs;
    },
    getInfos(){
      return this.infos;
    },
    getBlockNode(i) {
      return this.$refs[`blk_${i}`].getNode();
    },
    getCircleNode() {
      return this.$refs.circle.ccnode;
    },
    isBlockOut(node) {
        let idx = node.block_idx;
        //let block = this[`$blk${idx}`];
        //let bvs = block.getVertexs();
        let allvers = this.getAllVers();
        let blkvs = allvers.items || [];
        let vers = cals_node_vertexs(node, blkvs[idx]);
        for (let i = 0, l = vers.length; i < l; ++i) {
            if (this.isVertexOut(vers[i])) {
                return true;
            }
        }
        return false;
    },
    isVertexOut(v) {
        if (v.x < -1024 || v.x > 1024) {
            return true;
        }
        if (v.y < -768 || v.y > 768) {
            return true;
        }
        return false;
    },
    
    //////////////////////////////////
    onMoveEnd(idx) {
        let respt = this.respt;
        let ressz = this.ressz;
        let halfwidth = ressz.width / 2;
        let halfheight = ressz.height / 2;

        let node = this.getBlockNode(idx);

        if (
            cc_rectContainsPoint(
                cc.rect(
                    respt.x - halfwidth,
                    respt.y - halfheight,
                    ressz.width,
                    ressz.height
                ),
                cc_p(node.x, node.y)
            )
        ) {
            this.onOptEnd(idx);
        } else {
            let infos = this.getInfos();
            let sinf = infos[idx];

            let allvers = this.getAllVers();
            let position = allvers.positions[idx];
            let sc = allvers.scale;

            this.setStateBlockInfo(idx,{
                x: position.x,
                y: position.y,
                r: 0,
                f: 0,
                s: sc,
                i: 0,
                z:sinf.z,
            });
        }
    },

    onOptEnd(idx) {
        let node = this.getBlockNode(idx);

        let allvers = this.getAllVers();
        let blkvs = allvers.items || [];
        let vers = cals_node_vertexs(node, blkvs[idx]);

        let off = this.try_attach_point(vers, idx);
        if (off) {
            //console.log('onOptEnd attach', off);
            let x = node.x + off.x;
            let y = node.y + off.y;
            node.x = x;
            node.y = y;

            vers = cals_node_vertexs(node, blkvs[idx]);

            let ret = this.try_rotato_line(cc_p(x, y), vers, idx);
            if (ret) {
                //console.log('onOptEnd rotato', ret);
                let r = node.angle - ret.r;
                if (r < 0) {
                    r += 360;
                }
                node.angle = Math.floor(r + 0.4);

                vers = cals_node_vertexs(node, blkvs[idx]);
                off = this.try_attach_result(vers);
                if (off) {
                    //console.log('onOptEnd atcres', off);
                    x = node.x + off.x;
                    y = node.y + off.y;
                    node.x = x;
                    node.y = y;
                }
            }
        }
        this.optEndInfo(idx);
    },

    optEndInfo(idx) {
        const allvers = this.getAllVers();
        let circleRadius = this.circleRadius;
        let revbtnRadius = this.revbtnRadius;

        // debug
        // {
        //     let blkvs = allvers.items || [];
        //     let trivers = [];
        //     for (let i = 0, l = blkvs.length; i < l; ++i) {
        //         let block = this[`$blk${i}`];
        //         let node = block.getBlockNode();
        //         trivers[i] = cals_node_vertexs(node, blkvs[i]);
        //     }
        //     console.log('optEndInfo', mergeToVertexLines(trivers));
        // }

        // 修改信息
        let node = this.getBlockNode(idx);
        let infos = this.getInfos();
        let info = infos[idx];

        // 计算操作栏
        let sizes = allvers.sizes || [];
        let sz = Math.max(sizes[idx].height, sizes[idx].width);
        let scale = sz / circleRadius;
        this.setStateCirclePos({
            x: node.x,
            y: node.y,
            s: scale,
            h: revbtnRadius * scale,
            r: info.r,
        });

        // 修改信息
        this.setStateBlockInfo(idx,{
            x: node.x,
            y: node.y,
            r: node.angle,
            f: node.scaleX < 0 ? 1 : 0,
            s: 1,
            i: 1,
            z:info.z,
        });
    },

    try_rotato_line(center, vers, idx) {
        const allvers = this.getAllVers();

        let resvs = allvers.resvs || [];
        let lastret = null;
        for (let i = 0, l = resvs.length; i < l; ++i) {
            let v = resvs[i];
            let ret = vertexs_rotato_line(
                center,
                vers,
                v,
                ATTACH_MINANG,
                ATTACH_MINDIS / 2
            );
            if (ret) {
                if (!lastret || Math.abs(lastret.r) > Math.abs(ret.r)) {
                    lastret = ret;
                }
            }
        }
        if (lastret) {
            return lastret;
        }

        let infos = this.getInfos();
        let blkvs = allvers.items || [];
        for (let i = 0, l = blkvs.length; i < l; ++i) {
            if (i !== idx && infos[i].i) {
                let node = this.getBlockNode(i);
                let v = cals_node_vertexs(node, blkvs[i]);
                let ret = vertexs_rotato_line(
                    center,
                    vers,
                    v,
                    ATTACH_MINANG,
                    ATTACH_MINDIS / 2
                );
                if (ret) {
                    if (!lastret || Math.abs(lastret.r) > Math.abs(ret.r)) {
                        lastret = ret;
                    }
                }
            }
        }
        if (lastret) {
            return lastret;
        }
    },

    try_attach_point(vers, idx) {
        const allvers = this.getAllVers();

        let infos = this.getInfos();
        let trivers = [];
        let lastret = null;
        let blkvs = allvers.items || [];

        // 判断点是否和答案端点重合
        let resvs = allvers.resvs || [];
        for (let i = 0, l = resvs.length; i < l; ++i) {
            let v = resvs[i];
            trivers.push(v);
            let ret = vertexs_attach_polygon(vers, v, ATTACH_MINDIS_SQ);
            if (ret) {
                if (!lastret || cc_pLengthSQ(lastret) > cc_pLengthSQ(ret)) {
                    lastret = ret;
                }
            }
        }
        if (lastret) {
            return lastret;
        }

        // 判断点是否和现有块端点重合
        for (let i = 0, l = blkvs.length; i < l; ++i) {
            if (i !== idx && infos[i].i) {
                let node = this.getBlockNode(i);
                let v = cals_node_vertexs(node, blkvs[i]);
                trivers.push(v);
                let ret = vertexs_attach_polygon(vers, v, ATTACH_MINDIS_SQ);
                if (ret) {
                    if (!lastret || cc_pLengthSQ(lastret) > cc_pLengthSQ(ret)) {
                        lastret = ret;
                    }
                }
            }
        }
        if (lastret) {
            return lastret;
        }

        // 判断点是否落在现有块边上
        for (let i = 0, l = trivers.length; i < l; ++i) {
            let ret = vertexs_attach_line(vers, trivers[i], ATTACH_MINDIS_SQ);
            if (ret) {
                if (!lastret || cc_pLengthSQ(lastret) > cc_pLengthSQ(ret)) {
                    lastret = ret;
                }
            }
        }
        if (lastret) {
            return lastret;
        }
    },

    try_attach_result(vers) {
        const allvers = this.getAllVers();

        // 判断点是否和答案端点重合
        let resvs = allvers.resvs || [];
        let lastret = null;
        let trivers = [];
        for (let i = 0, l = resvs.length; i < l; ++i) {
            let v = resvs[i];
            trivers.push(v);
            let ret = vertexs_attach_polygon(vers, v, ATTACH_MINDIS_SQ);
            if (ret) {
                if (!lastret || cc_pLengthSQ(lastret) > cc_pLengthSQ(ret)) {
                    lastret = ret;
                }
            }
        }
        if (lastret) {
            return lastret;
        }

        // 判断点是否落在答案边上
        for (let i = 0, l = trivers.length; i < l; ++i) {
            let ret = vertexs_attach_line(vers, trivers[i], ATTACH_MINDIS_SQ);
            if (ret) {
                if (!lastret || cc_pLengthSQ(lastret) > cc_pLengthSQ(ret)) {
                    lastret = ret;
                }
            }
        }
        if (lastret) {
            return lastret;
        }
    },
    //////////////////////////////////
    handleTouchStart(touch) {
      let pt = cc_convertToNodeSpaceAR(this.getTopNode(),touch.getLocation());

      let orders = this.getOrders();
      let allvers = this.getAllVers();
      let blkvs = allvers.items || [];

      // 如果有旋转操作栏，判断是否操作栏操作
      let cminRadius = this.cminRadius;
      let cmaxRadius = this.cmaxRadius;

      let crlpt = this.crlpt;
      if (crlpt) {
          let dis = cc_pDistanceSQ(cc_p(crlpt.x, crlpt.y), pt);
          let minr = cminRadius * crlpt.s;
          let maxr = cmaxRadius * crlpt.s;
          //console.log('handleTouchStart', dis, minr, maxr);
          if (dis > minr * minr && dis < maxr * maxr) {
              let center = cc_p(crlpt.x, crlpt.y);
              let startvec = cc_pSub(pt, center);

              let idx = orders[orders.length - 1];
              let node = this.getBlockNode(idx);
              let rot = node.angle
              this.curTouchInfo = {
                  startrot: rot,
                  touchpt: pt,
                  center,
                  startvec,
              };
              // console.log('handleTouchStart crlpt');
              return;
          }
      }

      for (let i = orders.length - 1; i >= 0; --i) {
          let idx = orders[i];
          let node = this.getBlockNode(idx);
          let vers = cals_node_vertexs(node, blkvs[idx]);
          if (cc_pointInPolygon(pt, vers)) {
              this.curTouchInfo = {
                  startpt: cc_p(node.x, node.y),
                  touchpt: pt,
              };
              this.currTouchNode = node;
              this.currTouchNode.block_idx = idx;
              this.onPictureTouch(idx);
              return;
          }
      }
    },
    handleTouchMove(delta, touch) {
        if (this.currTouchNode) {
            this.onPictureMove(delta, touch);
            return;
        }
        if (this.curTouchInfo) {
            this.onPictureRotate(touch);
        }
    },
    handleTouchEnd(delta, touch) {
        if (this.currTouchNode) {
            this.onPictureMoveEnd(delta, touch);
            return;
        }
        if (this.curTouchInfo) {
            this.onPictureRotateEnd(touch);
        }
    },
    handleClick() {
        if (this.currTouchNode) {
            this.onPictureClick(this.currTouchNode.block_idx);
        }
    },

    //////////////////////////////////
    onPictureTouch(index) {
        // qs_play_audio(this.props, this.props.selectAudio);
        this.setStateBlockOrder(index,true);
        this.setStateCirclePos(null);
    },
    onPictureMove(delta, touch) {
        if (this.curTouchInfo) {
            let pt = cc_convertToNodeSpaceAR(this.getTopNode(),touch.getLocation());
            let old = cc_p(this.currTouchNode.x, this.currTouchNode.y);
            let to = cc_pAdd(
                this.curTouchInfo.startpt,
                cc_pSub(pt, this.curTouchInfo.touchpt)
            );
            this.currTouchNode.x = to.x;
            this.currTouchNode.y = to.y;
            if (this.isBlockOut(this.currTouchNode)) {
                this.currTouchNode.x = old.x;
                this.currTouchNode.y = old.y;
            }else{
                this.setStateBlockPos(this.currTouchNode.block_idx,to);
            }
            return;
        }
        // console.log('onPictureMove no curTouchInfo');
        // this.currTouchNode.x += delta.x;
        // this.currTouchNode.y += delta.y;
        // if (this.isBlockOut(this.currTouchNode)) {
        //     this.currTouchNode.x -= delta.x;
        //     this.currTouchNode.y -= delta.y;
        //     //
        // }
    },
    onPictureMoveEnd(delta, touch) {
        // qs_play_audio(this.props, this.props.movendAudio);
        if (delta && touch) {
            this.onPictureMove(delta, touch);
        }
        this.onMoveEnd(this.currTouchNode.block_idx);//parseInt(this.currTouchNode.name)
    },
    onPictureClick(idx) {
        let circleRadius = this.circleRadius;
        let revbtnRadius = this.revbtnRadius;
        let infos = this.getInfos();
        let info = infos[idx];
        if (info.i) {
            // 计算操作栏
            let allvers = this.getAllVers();
            let sizes = allvers.sizes || [];
            let sz = Math.max(sizes[idx].height, sizes[idx].width);
            let scale = sz / circleRadius;
            this.setStateCirclePos({
                x: info.x,
                y: info.y,
                s: scale,
                h: revbtnRadius * scale,
                r: info.r,
            });
        }
    },
    onPictureReserve(idx) {
        // 修改信息
        let node = this.getBlockNode(idx);
        node.scaleX = -node.scaleX;

        // let infos = this.getInfos();
        // let info = infos[idx];
        // info.f = info.f ? 0 : 1;

        this.onOptEnd(idx);
    },
    onPictureRotate(touch) {
        let pt = cc_convertToNodeSpaceAR(this.getTopNode(),touch.getLocation());

        let vec = cc_pSub(pt, this.curTouchInfo.center);
        let ang =
            (cc_pAngleSigned(vec, this.curTouchInfo.startvec) * 180) / Math.PI;

        let orders = this.getOrders();
        let idx = orders[orders.length - 1];
        let node = this.getBlockNode(idx);
        node.angle = this.curTouchInfo.startrot - Math.floor(ang);
        this.getCircleNode().angle = node.angle;
	    this.setStateBlockRot(idx,node.angle);
    },
    onPictureRotateEnd(touch) {
        if (touch) {
            this.onPictureRotate(touch);
        }

        let orders = this.getOrders();
        let idx = orders[orders.length - 1];
        this.onOptEnd(idx);
    },

    //////////////////////////////////
    blockProps(i,vs){
      return {name:'block_'+i,x:vs.x,y:vs.y,scaleX:vs.f ? -vs.s : vs.s,scaleY:vs.s,angle:vs.r,zIndex:vs.z};
    },
    //////////////////////////////////
    createAllVertexs(){
      let allvertexs = this.formatVertexs(this.polyfile);
      allvertexs.scale = this.blksz / allvertexs.maxheight;
      allvertexs.scaleszs = allvertexs.sizes.map(sz => {
          return {
              width: sz.width * allvertexs.scale,
              height: sz.height * allvertexs.scale,
          };
      });
      let offs = allvertexs.offsets;
      let pts = [];
      let totalwidth = 0;
      for (let i = 0, l = allvertexs.scaleszs.length; i < l; ++i) {
          let sz = allvertexs.scaleszs[i];
          pts.push({
              x:
                  totalwidth +
                  sz.width / 2 +
                  this.blkpt.x -
                  offs[i].x * allvertexs.scale,
              y: this.blkpt.y - offs[i].y * allvertexs.scale,
          });
          totalwidth += this.blkcap;
          totalwidth += sz.width;
      }
      totalwidth -= this.blkcap;
      let halfwidth = totalwidth / 2;
      allvertexs.positions = pts.map(pt => {
          return { x: pt.x - halfwidth, y: pt.y };
      });
      return allvertexs;
    },
    createBlockInfo(avs){
        let positions = avs.positions || [];
        let sc = avs.scale;

        let ret = [];
        positions.forEach((p,idx)=>{
          ret.push(
              {
                    x: p.x, //i * blkcap - halfw + blkpt.x,
                    y: p.y, //blkpt.y,
                    r: 0,
                    f: 0,
                    s: sc,
                    i: 0,
                    z: idx,
              });
        });

        return ret;
    },
    //////////////////////////////////
    formatPolygon(vers) {
        // if (3 === vers.length) {
        //     return this.formatTriangle(vers);
        // }
        let minx = 10000,
            miny = 10000,
            maxx = -10000,
            maxy = -10000;
        for (let i = 0, l = vers.length; i < l; ++i) {
            if (vers[i].x < minx) {
                minx = vers[i].x;
            }
            if (vers[i].x > maxx) {
                maxx = vers[i].x;
            }
            if (vers[i].y < miny) {
                miny = vers[i].y;
            }
            if (vers[i].y > maxy) {
                maxy = vers[i].y;
            }
        }
        // let cx = Math.floor((maxx - minx) / 2);
        // let cy = Math.floor((maxy - miny) / 2);
        let width = Math.floor(maxx - minx);
        if (width & 1) {
            width++;
        }
        let height = Math.floor(maxy - miny);
        if (height & 1) {
            height++;
        }
        let cx = width / 2;
        let cy = height / 2;
        let tx = cx + minx;
        let ty = cy + miny;
        let vs = [];
        for (let i = 0, l = vers.length; i < l; ++i) {
            let x = vers[i].x - tx;
            let y = vers[i].y - ty;
            vs.push({ x, y });
        }
        return {
            vertexs: vs,
            offset: cc_p(tx, ty),
            size: { width, height },
        };
    },
    formatResult(avers) {
        let minx = 10000,
            miny = 10000,
            maxx = -10000,
            maxy = -10000;

        const { items, xyrf } = avers;
        let len = xyrf.length;
        let vers = [];

        for (let i = 0; i < len; ++i) {
            let rf = xyrf[i];
            let item = rf.i ? items[rf.i - 1] : items[i];
            let vs = cals_xyrf_vertexs(rf, item);
            vers.push(vs);

            for (let j = 0, l = vs.length; j < l; ++j) {
                if (vs[j].x < minx) {
                    minx = vs[j].x;
                }
                if (vs[j].x > maxx) {
                    maxx = vs[j].x;
                }
                if (vs[j].y < miny) {
                    miny = vs[j].y;
                }
                if (vs[j].y > maxy) {
                    maxy = vs[j].y;
                }
            }
        }
        let width = Math.floor(maxx - minx);
        if (width & 1) {
            width++;
        }
        let height = Math.floor(maxy - miny);
        if (height & 1) {
            height++;
        }
        let cx = width / 2;
        let cy = height / 2;
        let tx = cx + minx;
        let ty = cy + miny;

        let offset = cc_p(tx, ty);
        let ct = cc_pSub(this.respt, offset);

        let its = vers.map(p => {
            return p.map(v => {
                return {
                    x: v.x + ct.x,
                    y: v.y + ct.y,
                };
            });
        });

        return { offset, resvs: its };
    },
    formatVertexs(avers) {
      let maxsz = 0;
      let maxheight = 0; //
      let items = [];
      let sizes = [];
      let offsets = [];
      if (avers.items && avers.items.length) {
          for (let i = 0, l = avers.items.length; i < l; ++i) {
              //items.push(avers.items[i]);
              let fmtvs = this.formatPolygon(avers.items[i]);
              // let fmtvs = this.formatPolygon(avers.items[i]);
              items.push(fmtvs.vertexs);
              sizes.push(fmtvs.size);
              offsets.push(fmtvs.offset);

              if (maxsz < fmtvs.size.width) {
                  maxsz = fmtvs.size.width;
              }
              if (maxsz < fmtvs.size.height) {
                  maxsz = fmtvs.size.height;
              }
              if (maxheight < fmtvs.size.height) {
                  maxheight = fmtvs.size.height;
              }
          }
      }

      let { offset, resvs } = this.formatResult(avers);
      offsets.push(offset);

      return {
          src: avers.items,
          items: avers.items,
          resvs,
          sizes,
          offsets,
          maxsz,
          maxheight,
          xyrf: avers.xyrf,
      };
    },

  },

};
</script>
